package cn.dagteam.springboot.mongodb.starter.listener;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.ReflectionUtils;

import cn.dagteam.springboot.mongodb.starter.Cascade;
import cn.dagteam.springboot.mongodb.starter.Cascade.CascadeType;
import lombok.AllArgsConstructor;

@AllArgsConstructor
public class CascadeSaveCallback implements ReflectionUtils.FieldCallback {

    private Object source;

    private MongoTemplate mongoTemplate;

    @Override
    public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
        try {
            PropertyDescriptor pd = new PropertyDescriptor(field.getName(), source.getClass());
            Object value = ReflectionUtils.invokeMethod(pd.getReadMethod(), source);
            if (value != null) {
                Cascade cascade = field.getAnnotation(Cascade.class);
                CascadeType[] types = cascade.value();
                Arrays.stream(types).filter(p -> CascadeType.ALL.equals(p) || CascadeType.SAVE.equals(p)).findAny().ifPresent(p -> {
                    if (value instanceof Collection) {
                        Collection<?> cols = (Collection<?>) value;
                        if (!cols.isEmpty()) {
                            for (Object col : cols) {
                                if (col != null) {
                                    mongoTemplate.save(col);
                                }
                            }
                        }
                    } else {
                        mongoTemplate.save(value);
                    }
                });
            }
        } catch (IntrospectionException e) {
            throw new RuntimeException("不是javabean的对象", e);
        }
    }
}
